<?
function get_attrs($a = false, $b = false, $c = false){
    static $attr;
    if (func_num_args() == 0){
        return $attr;
    }
    if ($b == "TEMPLATE" || 
    	$b == "ACTION")
    	$attr = $c;
}

function temp(){}

function tag_serialize($v)
{                                                                                                                  
    $id = uniqid("");
    $GLOBALS["_CTAG_VARS"][$id] = $v;
    return "$".$id;
}

class PostFilterCTags{
    var $area = "visitor";
    var $_vars = array();
    function PostFilterCTags($area, $vars)
    {
        $this->area = $area;
        $this->_vars = $vars;
    }

    function parse($text)
    {
        $this->parseTag($text, "action", "_processAction");
        $this->parseTag($text, "template", "_processTemplate");
        return $text;
    }

    function compile($text)
    {
        return $text;
    }

    function _doAction(&$text, $pos, $length, $handler, $isShort = false)
    {       
        $r = substr($text, $pos, $length);
        if ($isShort){
            $xml = $r;
            $inner = "";
        }else{ 
            $start = strpos($r, ">");
            $end = strrpos($r, "<");
            $inner = substr($r, $start+1, $end - $start-1);
            $xml = substr($r, 0, $start+1).substr($r, $end);
        }
        $parser = xml_parser_create();
        xml_set_element_handler($parser, "get_attrs", 'temp');
        xml_parse($parser, str_replace("cmf:","",$xml));

        $attrs = array();
        foreach (get_attrs() as $k => $v)
            $attrs[strtolower($k)] = $v;
        $r1 = $this->$handler($attrs, $inner);
        $res = strlen($r1) - strlen($r);
        $text = str_replace($r, $r1, $text);
        return $res;
    }

    function _doAction1($xml, $handler)
    {
        $parser = xml_parser_create();
        xml_set_element_handler($parser, "get_attrs", 'temp');
        xml_parse($parser, str_replace("cmf:","",$xml));

        $attrs = array();
        foreach (get_attrs() as $k => $v)
            $attrs[strtolower($k)] = $v;
        return $this->$handler($attrs, "");
    }

    function parseTag(&$text, $tag, $handler)
    {       
        if (strlen($text) == 0) return;
        preg_match_all("/(<cmf:{$tag}[^\/]+\/>)/", $text, $all);
        foreach ($all[1] as $v)
            $text = str_replace($v, $this->_doAction1($v, $handler), $text);

        $positions = array();
        $pos = 0;
        $closeTagLen = 4 + strlen($tag) + 1;
        while ( ($pos = strpos($text, "cmf:{$tag}", $pos)) !== false){
            if ($text[$pos-1] == "<"){
                //open tag
                array_push($positions, $pos-1);
            } else {
                //close tag
                $startPos = array_pop($positions);
                $this->_doAction($text, $startPos, $pos-$startPos + $closeTagLen, $handler);
                $pos = $startPos;
            }
            $pos++;
        }        
    }

    function _processAction($attrs, $inner)
    {
        if (!$attrs["name"] && !$attrs["mod"])
            return "";
        $area = $attrs['area'];
        if (!$area)
        $area = $this->area;
/*         if ($area == "member2" && intVal($_SESSION['member']['id']) == 0){
            header("Location: /");
            exit;
        } */
        /*if (!isset($_SESSION[$area]['id']) || $_SESSION[$area]['id'] == 0){
        $view = new View("tpl/no_access");
        return $view->fetch();            
        }*/
        $ctrl = Controller::factory($area, $attrs['mod']);
        $method = "process".Controller::_formatName($attrs['name']);
        $req = new Request(array_merge($_GET, $_POST), get_magic_quotes_gpc());
        if (!method_exists($ctrl, $method)){
            if(_cfg('debug'))
                _d("could not found ".get_class($ctrl)."::".$method);
            else
                $req->forward(_cfg('url'));
            exit;
        }
        foreach ($attrs as $n => $v)
            if ($n != "mod" && $n != "name" && $n != "area")
                $req->set($n, $v);
        $tpl = $ctrl->$method($req);
        $tpl = $tpl->fetch();
        if ($errors = $ctrl->getErrors())
			$req->addErrors($errors);
		return $tpl;
    }

    function _processTemplate($attrs, $inner)
    {
        $name = $attrs["name"];
        if ($pos = strpos($name,'.')){
        	$path = _cfg("path")."/_inc/mod/".substr($name, 0 ,$pos)."/tpl/_cmf.templates/";
        	$path1 = "/mod/".substr($name, 0 ,$pos)."/tpl/_cmf.templates/";
        	$name = substr($name, $pos+1);        	
        } else {
        	$path = _cfg("path")."/_inc/tpl/_cmf.templates/";
        	$path1 = "/tpl/_cmf.templates/";
        }
        if (!file_exists($path.$name.".php")){            
            $info = array(
                'errNo'  => "Custom",
                'errMsg' => "could not found "."/_cmf.templates/".$name.".php template",
                'files'  => array(),
            );
            $files = debug_backtrace();
            for ($i=1, $n=sizeof($files); $i<$n; ++$i)
                $info['files'][] = $files[$i]['line'].' , '.$files[$i]['file'];
            _d($info, 1);
        }
        $tpl = new View($path1."/$name");

		//_includeJs("blocks/".$name.".js");
		//_includeCss("blocks/".$name.".css");

        foreach ($attrs as $n => $v){
            if ($n != "name")
                if ($v[0] == "$"){
                    $tpl->setVar($n, $GLOBALS["_CTAG_VARS"][substr($v,1)], false);
                }else
                    $tpl->setVar($n, $v, false);
        }
        $tpl->setVar("html",$inner, 0);
        $req = new Request(array_merge($_GET, $_POST), get_magic_quotes_gpc());
        $tpl->setVar("req", $req);
        return $tpl->fetch();
    }

}

?>
